package org.xurui.bsj.protocol.command.impl;

import lombok.extern.slf4j.Slf4j;
import org.hswebframework.web.bean.FastBeanCopier;
import org.jetlinks.core.message.CommonDeviceMessage;
import org.jetlinks.core.message.DeviceMessage;
import org.jetlinks.core.message.codec.EncodedMessage;
import org.jetlinks.core.message.codec.FromDeviceMessageContext;
import org.jetlinks.core.message.event.EventMessage;
import org.jetlinks.core.message.function.FunctionInvokeMessage;
import org.jetlinks.core.message.function.FunctionParameter;
import org.jetlinks.core.message.property.WritePropertyMessage;
import org.springframework.util.StringUtils;
import org.xurui.bsj.protocol.command.CmdCodec;
import org.xurui.bsj.protocol.enums.CommandEnum;
import org.xurui.bsj.protocol.msg.BsjMessage;
import org.xurui.bsj.protocol.msg.BsjMessageBuilder;
import org.xurui.bsj.protocol.utils.ArrayUtils;
import org.xurui.bsj.protocol.utils.BinaryUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 4.1.12. 获取天气信息
 */
@Slf4j
public class CmdCodec_GET_WEATHER_INFO implements CmdCodec {
    @Override
    public boolean supportsCmd(String cmd) {
        return CommandEnum.GET_WEATHER_INFO.name().equals(cmd);
    }

    @Override
    public List<DeviceMessage> parsePayload(BsjMessage payload, FromDeviceMessageContext context) {
        //例子：[35380100360174,898600MFSSYYGXXXXXXP,201805082000001000,GET_WEATHER_INFO,3,20180528111820,106,0E121.411783N31.178125T20
        //080121165030@460!0!9231!2351@wifi!AC:BC:32:78:A2:5F!-97#wifi1!A
        //C:BC:32:78:A2:5F!-97#wifi1!AC:BC:32:78:A2:5F!-97#wifi1!AC:BC:32:78:A
        //2:5F!-97#wifi1!AC:BC:32:78:A2:5F!97#wifi1!AC:BC:32:78:A2:5F!-97#wifi
        //1!AC:BC:32:78:A2:5F1-97#wifi1!AC:BC:32:78:A2:5F!-97#wifi1!AC:BC:32:7
        //8:A2:5F!-97#wifi1!AC:BC:32:78:A2:5F!-97#wifi1!AC:BC:32:78:A2:5F!-97#
        //wifi1!AC:BC:32:78:A2:5F!-97]
        /**
         * 报文内容格式： GPS 位置信息
         *             @LBS 数据
         *             @Wi-Fi 数据
         * 说明：与【位置上报】命令内容一致，详情参考【位置上报】命令。
         */
        //设备上报事件
        EventMessage eventMessage = new EventMessage();
        eventMessage.setDeviceId(payload.getHeader().getDeviceNo());
        eventMessage.setEvent(payload.getHeader().getCmd());
        eventMessage.setMessageId(payload.getHeader().getOrderNo());
        eventMessage.setTimestamp(System.currentTimeMillis());
        Map<String, Object> properties = new HashMap<>();
        String tempBody = payload.getTempBody();
        String[] tempBodyArr = tempBody.split("@");
        //properties.put("header", FastBeanCopier.copy(payload.getHeader(), HashMap::new));
        properties.put("header", payload.getHeader().toMap());

        /**
         * GPS 位置信息：遵循 NEMA 报文格式 GPS 上报 位置信息，参见附录 A；
         */
        if(!StringUtils.isEmpty(ArrayUtils.getStrByIndex(tempBodyArr,0))){
            Map map= BinaryUtils.getGps(tempBodyArr[0]);
            properties.put("gpsStatus",map.get("gpsStatus"));
            properties.put("lonBs",map.get("lonBs"));
            properties.put("longitude",map.get("longitude"));
            properties.put("latBs",map.get("latBs"));
            properties.put("latitude",map.get("latitude"));
            properties.put("timeBs",map.get("timeBs"));
            properties.put("time",map.get("time"));
        }

        /**
         *            460,0,9231,2351,-30: LBS 基站数据,MCC 国家码,460 为中国,0:MNC,0 为移动, 9231:LAC, 十进制, 2351,CID,十进制
         *            如果 GPS 数据包中状态为 1, 或者经纬度为” 0000.0000N00000.0000E”时,则取 LBS 数据
         */
        properties.put("LBS",ArrayUtils.getStrByIndex(tempBodyArr,1));
        /**
         * wifi!AC:BC:32:78:A2:5F!-97: 一组 WIFI 信 息，wifi 为 SSID，AC:BC:32:78:A2:5F 为 MAC 地址，-97 为信号强度，变量之间用“!”分隔开 WIFI 信 息可以有多组，每组之间用“#”分隔
         */
        properties.put("wifiArr",ArrayUtils.getStrByIndex(tempBodyArr,2));
        eventMessage.setData(properties);

        //回复消息
        //标识通信方向，取值如下: 1.下发请求 2.下发响应 3.上报请求 4.上报响应
        //说明：平台下发请求标示 1，则终 端响应标示为 2，终端上报接口标 示为 3，平台响应标示为 4
        //组装需要回复设备消息提
        /**
         * 报文内容格式：天气状态
         *             @最低温度!最高温度
         * 说明：       1.天气状态：例如：多云。
         *             2.温度：范围：-128 ~ 127。
         * 异常应答：0=无设置，1=非平台用户，2=其他
         * 异常
         */
        //TODO
        //示例：[35380100360174,898600MFSSYYGXXXXXXP,201805082000001000,GET_WEATHER_INFO,4,20180528111820,7,多云@32!35]
        payload.setWithOutRelayToDevice(true);
     //   payload.setTempReplyBody("多云@32!35");
        return genDeviceMessage(eventMessage);
    }


    @Override
    public EncodedMessage encodeMessage(CommonDeviceMessage message, String zzs) {
        //平台下发消息
        //例子：[35380100360174,898600MFSSYYGXXXXXXP,201805082000001000,GET_WEATHER_INFO,4,20180528111820,7,多云@32!35]
        /**
         * 报文体格式：
         * 天气状态@最低温度!最高温度
         * 说明：
         * 天气状态：例如：多云。
         * 温度：范围：-128 ~ 127。
         * 异常应答：0=无设置，1=非平台用户，2=其他异常
         */
        if(message instanceof WritePropertyMessage) {
            WritePropertyMessage m = (WritePropertyMessage) message;
            Map<String,Object> params = m.getProperties();
            String  wType = "";
            if(params.get("wType")!=null && !params.get("wType").equals("")) {
                wType=params.get("wType").toString();
            }
            String  nighttemp = "";
            if(params.get("nighttemp")!=null && !params.get("nighttemp").equals("")) {
                nighttemp=params.get("nighttemp").toString();
            }
            String  daytemp = "";
            if(params.get("daytemp")!=null && !params.get("daytemp").equals("")) {
                daytemp=params.get("daytemp").toString();
            }

            StringBuffer sb = new StringBuffer();
            sb.append(wType);
            sb.append(BinaryUtils.CMD_AT);
            sb.append(nighttemp);
            sb.append(BinaryUtils.CMD_EXCLAMATION);
            sb.append(daytemp);

            return BsjMessageBuilder.create().buildBsjWritePropertyMessage(m,sb.toString());
        }else{
            if (log.isDebugEnabled()) {
                log.debug("非WritePropertyMessage指令{}消息{}",CommandEnum.GET_WEATHER_INFO.name(),message);
            }
            return null;
        }

    }
}
